﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace MicroTest
{
    
    class SaveStrokeAsync
    {
        /// <summary>
        /// 待保存笔迹buffer
        /// </summary>
        private List<StrokeItem> StrokeListBuffer;
        /// <summary>
        /// 当前笔迹buff
        /// </summary>
        private Dictionary<string,StrokeItem> StrokeListTemp;
        /// <summary>
        /// lock对象
        /// </summary>
        private object obj;
        /// <summary>
        /// 计时器，用于保存书写数据
        /// </summary>
        System.Threading.Timer threadTimer;
        private bool IsSavingData = false;
        /// <summary>
        /// 异步存储坐标
        /// </summary>
        public SaveStrokeAsync()
        {
            StrokeListBuffer = new List<StrokeItem>();
            StrokeListTemp = new Dictionary<string, StrokeItem>();
            obj = new object();
            threadTimer = new System.Threading.Timer(saveStrokeAsync, null, Timeout.Infinite, 5000);
        }
        /// <summary>
        /// 保存坐标
        /// </summary>
        /// <param name="penserial"></param>
        /// <param name="pageserial"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void PutCoordinates(string penserial, string pageserial, int x, int y)
        {
            if (!StrokeListTemp.ContainsKey(penserial))
                return;
            StrokeListTemp[penserial].pageSerial = pageserial;
            StrokeListTemp[penserial].stroke.Add(new System.Drawing.Point(x, y));
        }
        /// <summary>
        /// 落笔
        /// </summary>
        /// <param name="penserial"></param>
        public void PutPenDownEvent(string penserial)
        {
            if(!StrokeListTemp.ContainsKey(penserial))
            {
                StrokeItem si = new StrokeItem();
                si.pointTime = DateTime.Now;
                si.stroke = new List<System.Drawing.Point>();
                si.PenSerial = penserial;
                StrokeListTemp.Add(penserial, si);
            }
        }
        /// <summary>
        /// 抬笔
        /// </summary>
        /// <param name="penserial"></param>
        public void PutPenUpEvent(string penserial)
        {
            if (!StrokeListTemp.ContainsKey(penserial))
                return;
            if (StrokeListTemp[penserial].stroke.Count == 0)
                return;
            StrokeItem si = new StrokeItem();
            si.pointTime = StrokeListTemp[penserial].pointTime;
            si.pageSerial = StrokeListTemp[penserial].pageSerial;
            si.PenSerial = StrokeListTemp[penserial].PenSerial;
            si.stroke = new List<System.Drawing.Point>(StrokeListTemp[penserial].stroke);
            StrokeListTemp[penserial].stroke.Clear();
            lock (obj)
            {
                StrokeListBuffer.Add(si);
            }
        }
        /// <summary>
        /// 异步存储缓冲区中的笔迹数据，每过5秒存储一次
        /// </summary>
        /// <param name="state"></param>
        private void saveStrokeAsync(object state)
        {

            IsSavingData = true;

            List<StrokeItem> tmp = null;
            lock (obj)
            {
                if (StrokeListBuffer.Count != 0)
                {
                    tmp = new List<StrokeItem>(StrokeListBuffer);
                    StrokeListBuffer.Clear();
#if DEBUG
                    Debug.WriteLine(string.Format("Get: size={0}", tmp.Count));
#endif
                }

            }
            if (tmp != null)
            {
                threadTimer.Change(Timeout.Infinite, 5000);
#if DEBUG
                Debug.WriteLine(string.Format("Write: size={0}", tmp.Count));
                //int j = 0;
#endif
                foreach (var item in tmp)
                {
                    string jsonFileName = Program.DATA_FOLDER + "\\" + item.PenSerial + ".json";
                    FileStream fs = File.Open(jsonFileName, FileMode.Append);
                    StreamWriter sw = new StreamWriter(fs);

                    //#if DEBUG
                    //                    Debug.WriteLine(string.Format("Write: Index={0}", ++j));
                    //#endif
                    JObject obj = new JObject();
                    obj["t"] = item.pointTime.ToString("yyyy-MM-dd_HH:mm:ss");
                    obj["p"] = item.pageSerial;
                    obj["n"] = item.stroke.Count;

                    JArray ja = new JArray();
                    for (int i = 0; i < item.stroke.Count; i++)
                    {
                        JObject jo = new JObject();
                        jo["x"] = item.stroke[i].X;
                        jo["y"] = item.stroke[i].Y;
                        ja.Add(jo);
                    }
                    obj["list"] = ja;
                    sw.WriteLine(obj.ToString().Replace("\r\n", "").Replace(" ", ""));
                    sw.Close();
                    fs.Close();
                }
                
#if DEBUG
                Debug.WriteLine("Write: Over");
#endif

                threadTimer.Change(5000, 5000);
            }
            IsSavingData = false;
        }

        /// <summary>
        /// 停止存储数据
        /// </summary>
        public void StopSaving()
        {
            while(IsSavingData)
            {
                Thread.Sleep(100);
            }
            threadTimer.Change(Timeout.Infinite, 5000);
        }
        /// <summary>
        /// 开始存储数据
        /// </summary>
        public void BeginSaving()
        {
            threadTimer.Change(0, 5000);
        }
    }
}
